using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Enemy : MonoBehaviour 
{
	public float speed;

	private Vector2 nextTarget;
	public Node lastNode;
	public int offset;
	private Vector2 velocity;

	private bool ready;
	private int nextStep;
	private Node goal;
	private List<Node> currentPath;


	private int layerMask = (1 << 7) | (1 << 8);
	public bool foundEnemy;
	private Transform enemy;
	private AStar astar;

	AnimationManager anim;


	public Vector2 walkPoints;
	public bool isHorizontal;
	float moveSpeed;
	bool flip;
	bool npc = true;

	void Start()
	{
		anim = GetComponent<AnimationManager>();

		astar = gameObject.AddComponent("AStar") as AStar;
		
		currentPath = new List<Node>();
		moveSpeed = speed-.5f;

	}

	
	public void AddObjective()
	{
		this.goal =  enemy.GetComponent<CollisionManager>().lastNode;
		
		transform.position = new Vector3(lastNode.transform.position.x, lastNode.transform.position.y, transform.position.z);
		
		this.currentPath = astar.Search(lastNode, this.goal);
		
		this.lastNode = currentPath[0];
		
		this.nextStep = 1;
		
		this.nextTarget = new Vector2(currentPath[nextStep].transform.position.x, currentPath[nextStep].transform.position.y);
		
		this.velocity = calculeVelocity(currentPath[nextStep].transform.position);

		this.ready = true;
	}

	void Update () 
	{
		int currentLayer = 0;
		
		float positionY = offset-transform.position.y;
		int intPositionY = ((int)positionY);
		
		float result = Mathf.Abs(positionY-intPositionY);
		
		if(result > .5f)
			currentLayer = (((int)(offset-transform.position.y+transform.localScale.y/2))*2)+2;
		else
			currentLayer = (((int)(offset-transform.position.y+transform.localScale.y/2))*2)+1;
		
		GetComponent<SpriteRenderer>().sortingOrder = currentLayer-1;

		if(foundEnemy && ready)
		{
			
			if (Mathf.Abs(nextTarget.x - transform.position.x) < .25f)
			{
				velocity.x = 0;
			}
			if (Mathf.Abs(nextTarget.y - transform.position.y) < .25f)
			{
				velocity.y = 0;
			}
			
			if (velocity.x == 0 && velocity.y == 0)
			{
				if (nextStep >= currentPath.Count - 1)
				{
					anim.StartAnim("Idle");
					GameObject.FindGameObjectWithTag("Player").SendMessage("HasFound",SendMessageOptions.DontRequireReceiver);
					ready = false;
					return;
				}

				nextStep++;
				
				nextTarget = new Vector2(currentPath[nextStep].transform.position.x, currentPath[nextStep].transform.position.y);
				
				velocity = calculeVelocity(currentPath[nextStep].transform.position);
				
				lastNode = currentPath[nextStep];
				
			}
			transform.Translate(velocity.x*speed*Time.deltaTime,velocity.y*speed*Time.deltaTime,0);
		}
		else if(npc)
		{
			if(!isHorizontal)
			{
				if(transform.position.y >= walkPoints.y && !flip)
				{
					moveSpeed =  -moveSpeed;
					flip = !flip;
				}
				if(transform.position.y <= walkPoints.x && flip)
				{
					moveSpeed =  -moveSpeed;
					flip = !flip;

				}
				transform.Translate(0,moveSpeed*Time.deltaTime,0);


				if(moveSpeed > 0)
				{
					if(!anim.HasAnimation("Back_Walk"))
					{
						anim.StartAnim("Back_Walk");
					}
				}
				else
				{
					if(!anim.HasAnimation("Front_Walk"))
					{
						anim.StartAnim("Front_Walk");
					}
				}
			}
			else
			{
				if(transform.position.x >= walkPoints.y && !flip)
				{
					moveSpeed =  -moveSpeed;
					flip = !flip;
				}
				if(transform.position.x <= walkPoints.x && flip)
				{
					moveSpeed =  -moveSpeed;
					flip = !flip;
					
				}

				transform.Translate(moveSpeed*Time.deltaTime,0,0);

				if(moveSpeed > 0)
				{
					if(!anim.HasAnimation("Right_Walk"))
					{
						anim.StartAnim("Right_Walk");
						anim.Flip();
					}
				}
				else
				{
					if(!anim.HasAnimation("Left_Walk"))
					{
						anim.StartAnim("Left_Walk");
					}
				}
			}
			
		}
	}

	public void recalculePath()
	{
		this.ready = false;
		
		this.goal = enemy.GetComponent<CollisionManager>().lastNode;
		
		this.currentPath = astar.Search(lastNode, this.goal);
		
		this.nextStep = 1;

		try
		{
			this.nextTarget = new Vector2(currentPath[nextStep].transform.position.x, currentPath[nextStep].transform.position.y);
		}
		catch (System.Exception e)
		{

		}

		if(currentPath.Count > 1)
		{
			this.velocity = calculeVelocity(currentPath[nextStep].transform.position);
			
			this.ready = true;
		}
	}

	Vector2 calculeVelocity(Vector3 target)
	{
		
		try
		{
			float x = (target.x - transform.position.x);
			float y = (target.y - transform.position.y);
			
			Vector2 returnVector = new Vector2(x,y);
			returnVector.Normalize();


			if(Mathf.Abs(returnVector.x) > Mathf.Abs(returnVector.y))
			{
				if(returnVector.x > 0)
				{
					if(!anim.HasAnimation("Right_Walk"))
					{
						anim.StartAnim("Right_Walk");
						anim.Flip();
					}
				}
				else
				{
					if(!anim.HasAnimation("Left_Walk"))
						anim.StartAnim("Left_Walk");
				}
			}
			else
			{
				if(returnVector.y > 0)
				{
					if(!anim.HasAnimation("Back_Walk"))
					{
						anim.StartAnim("Back_Walk");
						anim.Flip();
					}
				}
				else
				{
					if(!anim.HasAnimation("Front_Walk"))
					{
						anim.StartAnim("Front_Walk");
						anim.Flip();
					}
				}
			}

			return returnVector;
		}
		catch (System.Exception e)
		{
		}
		
		
		return Vector2.zero;
	}

	void FoundEnemy()
	{
		if(foundEnemy == false)
		{
			Vector3 target = GameObject.FindGameObjectWithTag("Player").transform.position;

			RaycastHit2D hit = Physics2D.Linecast(transform.position, target , layerMask);

			if(hit.collider == null)
			{
				GameObject.FindGameObjectWithTag("Player").SendMessage("HasFound",SendMessageOptions.DontRequireReceiver);

			}
		}
	}

	void Die()
	{
		anim.StartAnim("Die");
		Destroy(gameObject,1f);
		Destroy(this);
	}

	void OnTriggerEnter2D(Collider2D collider)
	{
		if(collider.tag == "Node")
		{
			if(collider.GetComponent<Node>() != lastNode)
			{
				lastNode = collider.GetComponent<Node>();
			}
		}
	}
}
